package com.fifth.sso.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fifth.common.pojo.dto.CommonResult;
import com.fifth.common.pojo.entity.*;
import com.fifth.sso.feign.BusinessFeign;
import com.fifth.sso.feign.PermissionFeign;
import com.fifth.sso.feign.UserFeign;
import com.fifth.sso.pojo.vo.GetPasswordWithMD5;
import com.fifth.sso.pojo.vo.LoginVo;
import com.fifth.sso.relam.LoginType;
import com.fifth.sso.relam.UserToken;
import com.fifth.sso.utils.WebUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("sso")
public class LoginController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private PermissionFeign permissionFeign;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private BusinessFeign businessFeign;

    @PostMapping("login")
    public CommonResult login(@RequestBody LoginVo loginVo) {
        Subject subject = SecurityUtils.getSubject();
        try {
            UserToken token = new UserToken(loginVo.getLoginType(), loginVo.getTelephone(), loginVo.getPassword());
            //交于shiro自定义realm中的认证方法
            subject.login(token);
            //生成token. (1)UUID生成一个唯一id并把该值保存到redis中 [2]通过JWT来生成token.[(1)头信息 (2)载体 (3)密钥]
            String uuid = UUID.randomUUID().toString().replace("-", "");
            if (loginVo.getLoginType().equals(LoginType.EMP_PHONE)) {
                //登录成功后的用户信息
                EmpInfo empInfo = (EmpInfo) subject.getPrincipal();
                //根据用户id查询该用户具有的权限。
                List<String> permissions = permissionFeign.permission(empInfo.getId());
                Map<String, Object> map = new HashMap<>();
                map.put("user", empInfo);
                map.put("permissions", permissions);
                map.put("loginType",loginVo.getLoginType());
                // 保存在redis中 value应该为包含用户信息以及该用户具有的权限
                redisTemplate.opsForValue().set(uuid, JSON.toJSONString(map), 24, TimeUnit.HOURS);
                return new CommonResult(2000, "登录成功", uuid);
            } else if (loginVo.getLoginType().equals(LoginType.USER_PHONE)) {

                UserInfo byPhone = userFeign.findByPhone(loginVo.getTelephone());
                Integer status = byPhone.getStatus();
                if (status==0) {
                    //登录成功后的用户信息
                    UserInfo userInfo = (UserInfo) subject.getPrincipal();
                    //查询该用户具有的权限。
                    List<UserPermission> list = userFeign.getPermission();
                    List<String> permissions = new ArrayList<>();
                    for (UserPermission userPermission : list) {
                        permissions.add(userPermission.getUrl());
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put("user", userInfo);
                    map.put("permissions", permissions);
                    map.put("loginType", loginVo.getLoginType());
                    // 保存在redis中 value应该为包含用户信息以及该用户具有的权限
                    redisTemplate.opsForValue().set(uuid, JSON.toJSONString(map), 24, TimeUnit.HOURS);
                    return new CommonResult(2000, "登录成功", uuid);
                }
                return new CommonResult(4000,"该用户以冻结，请联系管理员",null);
            } else {
                //登录成功后的用户信息
                BusinessInfo businessInfo = (BusinessInfo) subject.getPrincipal();
                //查询商家具有的权限。
                List<BusinessPermission> list = businessFeign.getPermission();
                List<String> permissions = new ArrayList<>();
                for (BusinessPermission businessPermission : list) {
                    permissions.add(businessPermission.getUrl());
                }
                Map<String, Object> map = new HashMap<>();
                map.put("user", businessInfo);
                map.put("permissions", permissions);
                map.put("loginType",loginVo.getLoginType());
                // 保存在redis中 value应该为包含用户信息以及该用户具有的权限
                redisTemplate.opsForValue().set(uuid, JSON.toJSONString(map), 24, TimeUnit.HOURS);
                return new CommonResult(2000, "登录成功", uuid);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult(5000, "账号或密码错误", null);
        }
    }
    @PostMapping("sign")
    public String sign(@RequestParam String password,@RequestParam String salt){
        return  GetPasswordWithMD5.salt(password,salt);
    }

    /**
     * 退出登录的方法
     * @return
     */
    @GetMapping("loginOut")
    public CommonResult loginOut(){
        HttpServletRequest request = WebUtils.getRequest();
        String token = request.getHeader("token");
        if (token!=null) {
            redisTemplate.delete(token);
        }
        return new CommonResult(2000,"退出成功",null);
    }

    /**
     * 判断是否登录  是否为商家登录
     */
    @GetMapping("isLoginAndBusiness")
    public CommonResult isLoginAndBusiness(){
        String token = WebUtils.getRequest().getHeader("token");
        if(token!=null && token!="") {
            Boolean hasKey = redisTemplate.hasKey(token);
            if (hasKey == true) {
                Map map = JSON.parseObject(redisTemplate.opsForValue().get(token), Map.class);
                String loginType = (String) map.get("loginType");
                if (loginType.equals("USER_PHONE")) {
                    return new CommonResult(2000, "用户登录", "USER_PHONE");
                } else {
                    return new CommonResult(2000, "商家登录", "BUSINESS_PHONE");
                }
            }
        }
        return new CommonResult(5000,"未登录",null);
    }

}





















